﻿using Common;
using Common.FrontEnd;
using FrontEnd;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Linguist.Acoustic.Tiedstate
{
    /// <summary>
    /// Implements a Senone that contains a cache of the last scored data.
    ///
    /// Subclasses should implement the abstract {@link #calculateScore} method,
    /// which is called by the {@link #getScore} method to calculate the score
    /// for each cache miss.
    ///
    /// Note: this implementation is thread-safe and can be safely used
    /// across different threads without external synchronization.
    ///
    /// @author Yaniv Kunda
    /// </summary>
    public abstract class ScoreCachingSenone : ISenone
    {
        private class ScoreCache {
            public IData feature;
            public float score;

            public ScoreCache(IData feature, float score) 
            {
                this.feature = feature;
                this.score = score;
            }
        }

        private volatile ScoreCache scoreCache = new ScoreCache(null, 0.0f);

        /**
        /// Gets the cached score for this senone based upon the given feature.
        /// If the score was not cached, it is calculated using {@link #calculateScore},
        /// cached, and then returned.  
         */
        public float getScore(IData feature) {
            ScoreCache cached = scoreCache;
            if (feature != cached.feature) {
                cached = new ScoreCache(feature, calculateScore(feature));
                scoreCache = cached;
            }
            return cached.score;
        }

        /**
        /// Calculates the score for this senone based upon the given feature.
         *
        /// @param feature the feature vector to score this senone against
        /// @return the score for this senone in LogMath log base
         */
        public abstract float calculateScore(IData feature);


        float ISenone.getScore(IData feature)
        {
            throw new NotImplementedException();
        }

        float[] ISenone.calculateComponentScore(IData feature)
        {
            throw new NotImplementedException();
        }

        long ISenone.getID()
        {
            throw new NotImplementedException();
        }

        void ISenone.dump(string msg)
        {
            throw new NotImplementedException();
        }

        float[] ISenone.getLogMixtureWeights()
        {
            throw new NotImplementedException();
        }

        void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        {
            throw new NotImplementedException();
        }
        /**
       /// Returns the mixture components associated with this Gaussian
        *
       /// @return the array of mixture components
        */
        public IMixtureComponent[] getMixtureComponents()
        {
            throw new NotImplementedException();
        }
    }
}
